package com.snda.dw.lidejia.hdfsoverftp;

import java.io.IOException;

import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpFile;
import org.apache.ftpserver.ftplet.User;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HdfsFileSystemView
        implements FileSystemView {

    private static final Logger LOGGER = LoggerFactory.getLogger(HdfsFileSystemView.class);
    //
    private String currDir = "/";
    private User user;
    private final FileSystem dfs;
    //

    protected HdfsFileSystemView(User user, FileSystem fs)
            throws FtpException {
        if (user == null) {
            throw new IllegalArgumentException("user can not be null");
        }
        if (user.getHomeDirectory() == null) {
            LOGGER.info(String.format("Home Directory: %s", user.getHomeDirectory()));
            throw new IllegalArgumentException("User home directory can not be null");
        }
        try {
            if (!fs.exists(new Path(user.getHomeDirectory()))) {
                fs.mkdirs(new Path(user.getHomeDirectory()));
            }
        } catch (IOException e) {
            LOGGER.error(String.format("Creating home directory for user %s error", user.getName()), e);
            throw new FtpException(e);
        }

        if (fs == null) {
            throw new IllegalArgumentException("File system can not be null");
        }

        this.currDir = user.getHomeDirectory();
        this.user = user;
        this.dfs = fs;
    }

    @Override
    public FtpFile getHomeDirectory() {
        String homeDirectory = user.getHomeDirectory();
        return new HdfsFtpFile(homeDirectory, user, dfs);
    }

    @Override
    public FtpFile getWorkingDirectory() {
        return new HdfsFtpFile(currDir, user, dfs);
    }

    @Override
    public FtpFile getFile(String file) {
        LOGGER.info(String.format("Getting file: %s", file));
        //
        String path;
        if (file.startsWith("/")) {
            //path = file;
            if (file.startsWith(user.getHomeDirectory())) {
                path = file;
            } else {
                path = user.getHomeDirectory() + file;
            }
        } else {
            if (this.currDir.length() > 1) {
                path = this.currDir + "/" + file;
            } else {
                path = "/" + file;
            }
        }
        LOGGER.info(String.format("Path is %s", path));
        return new HdfsFtpFile(path, user, dfs);
    }

    @Override
    public boolean changeWorkingDirectory(String dir) {
        String path;
        if (dir.startsWith("/")) {
            //path = dir;
            if (dir.startsWith(user.getHomeDirectory())) {
                path = dir;
            } else {
                path = user.getHomeDirectory() + dir;
            }
        } else {
            if (dir.equals("..")) {
                if (!new Path(currDir).toString().equals("/")
                        && new Path(currDir + "/..").toString().startsWith(user.getHomeDirectory())) {
                    path = currDir + "/..";
                } else {
                    path = user.getHomeDirectory();
                }
            } else if (dir.startsWith("~")) {
                path = user.getHomeDirectory() + dir.substring(1);
            } else if (this.currDir.length() > 1) {
                path = this.currDir + "/" + dir;
            } else {
                path = "/" + dir;
            }
        }
        HdfsFtpFile file = new HdfsFtpFile(path, this.user, this.dfs);
        if ((file.isDirectory()) && (file.isReadable())) {
            this.currDir = path;
            return true;
        }
        return false;
    }

    @Override
    public boolean isRandomAccessible() {
        return true;
    }

    @Override
    public void dispose() {
    }
}